// SSW-556 Software Development for Trusted Systems
//
// Team 1: Anthony Favia, Gemma Anible, Lynn Lin
// Project 11
//
// Static analysis tools: Understand, CppCheck

#include <iostream>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

// Non-detectable flaw: Race condition
// 
// Mitigation strategies:
// - Check the result of thread synchronization functions and appropriately
//   handle all errors, either by attempting to recover from them or reporting
//   them to higher levels.
// - Use a lock (mutex/semaphore) to prevent multiple simultaneous requests to
//   the application.
// - Insert breakpoints or delays in between unsafe code statements to
//   artificially expand the race window.
void *myGlobal;
void myRace(int dummy) {
    free (myGlobal);
    sleep(10);
    exit(0);
}

// Non-detectable flaw: Null pointer reference
//
// Mitigation strategies:
// - Enforce coding standards that require checks for NULL pointer values prior
//   to referencing them.
// - Use exception handling to gracefully degrade when NULL pointer reference
//   exceptions are encountered.
// - Use "smart" pointers, that internally track values and reference counts.
void nullPtrUse(int * ptr)
{
    std::cout << *ptr;
}

// Non-detectable flaw: Hard-coded credentials
//
// Mitigation strategies:
// - Enforce coding conventions that forbid hard-coded passwords.
// - Use unit testing to verify randomly generated passwords.
int VerifyAdmin(const char *password) {
    if (strcmp(password, "SW556")) {

        std::cout << "Incorrect Password!" << std::endl;
        return(0);
    }
    std::cout << "Entering Diagnostic Mode..." << std::endl;
    return(1);
}

// Detectable flaw: Buffer overflow
void manipulate_string(char* string){
    char buf[22];
    strcpy(buf, string);
}

// Detectable flaw: Unreachable code
bool dummy_file() {
    return true;
}

// Detectable flaw: Buffer overflow
void bufOverflow(char arr[], int size)
{
    for ( int i = 0; i < size; i++ )
    {
        std::cout << arr[i];
    }
}
void callbufOverflow()
{
    int i = 10;
    char arr[5];

    strcpy(arr, "hello");

    bufOverflow(arr, i);
}

// Detectable flaw: Uninitialized variable use
void uninitializedVar()
{
    char *p;
    
    std::cout << p;
}

int main()
{
    char *my_test_string = (char *) "This string is longer than the buffer. Will cause buffer overflow!\n";

    // Detectable flaw: Buffer overflow
    manipulate_string (my_test_string);

    // Detectable flaw: Uninitialized variable use
    uninitializedVar();

    // Detectable flaw: Buffer overflow
    callbufOverflow();

    // Non-detectable flaw: Race condition
    myGlobal = (char*) malloc(128);
    signal (SIGHUP, myRace);
    signal (SIGTERM, myRace);
    sleep(10);

    // Non-detectable flaw: Hard-coded credentials
    VerifyAdmin("TestAdmin");

    // Non-detectable flaw: Null pointer reference
    int * p = NULL;
    nullPtrUse(p);

    exit (0);
}

